home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
Resources
/
Online
/
Term
/
Extras
/
Source
/
term-source.lha
/
StatusDisplay.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-20
|
29KB
|
1,324 lines
/*
** StatusDisplay.c
**
** Status information display routines
**
** Copyright © 1990-1996 by Olaf `Olsen' Barthel
** All Rights Reserved
**
** :ts=4
*/
#ifndef _GLOBAL_H
#include "Global.h"
#endif
/* The information to be displayed. */
enum {
INFO_STATUS,INFO_BUFFER,INFO_PROTOCOL,INFO_EMULATION,INFO_BAUDRATE,
INFO_PARAMETERS,INFO_CURRENTTIME,INFO_ONLINETIME,INFO_ONLINECOST,
INFO_UNITTIME
};
/* The current status line display mode. */
enum {
MODE_SCREEN_NORMAL,MODE_SCREEN_COMPRESSED,
MODE_WB_NORMAL,MODE_WB_COMPRESSED
};
/* Enumerated text boxes. */
enum {
STATUSBOX_STATUS_FONT,STATUSBOX_PROTOCOL_TERMINAL,
STATUSBOX_RATE_PARAMETERS,STATUSBOX_TIME_ONLINE
};
/* What to show in the online time box. */
enum {
SHOW_Cost,SHOW_OnlineTime,SHOW_UnitTime
};
/* The status server passes this structure to the
* rendering routine if the status information
* is to be updated.
*/
struct ObjectCarrier
{
struct RastPort *RPort;
LONG FirstColumn,
FullWidth;
struct TextBox **BoxArray,
*BoxList;
};
/* A custom message type for the display update server. */
struct UpdateMessage
{
struct Message Message;
APTR Object;
UBYTE Mode,
Type;
};
/* The following static strings are displayed in the status
* window.
*/
STATIC STRPTR ConfigBufferState[3],
ConfigEmulation[6],
ConfigParity[6];
/* The status modes and the corresponding text IDs. */
STATIC LONG ConfigStatusIDs[] =
{
MSG_TERMAUX_READY_TXT,
MSG_TERMAUX_HOLDING_TXT,
MSG_TERMAUX_DIALING_TXT,
MSG_TERMAUX_UPLOAD_TXT,
MSG_TERMAUX_DOWNLOAD_TXT,
MSG_TERMAUX_BREAKING_TXT,
MSG_TERMAUX_HANG_UP_TXT,
MSG_TERMAUX_RECORD_TXT,
MSG_AREXX_RUNNING_TXT
};
/* Width of the status line text, required in case the user interface
* font happens to be proportional-spaced.
*/
STATIC LONG StatusLineWidth;
/* The status display update task. */
STATIC struct Task *StatusDisplayTask;
STATIC struct MsgPort *StatusDisplayPort;
/* Display update data */
STATIC WORD UpdateSig;
STATIC ULONG UpdateMask;
STATIC BOOL NeedFullRefresh;
STATIC VOID
DrawSeparator(struct RastPort *RPort)
{
SetAPen(RPort,Pens[SHADOWPEN]);
RectFill(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayLeft + StatusDisplayWidth - 1,StatusDisplayTop);
SetAPen(RPort,Pens[SHINEPEN]);
RectFill(RPort,StatusDisplayLeft,StatusDisplayTop + 1,StatusDisplayLeft + StatusDisplayWidth - 1,StatusDisplayTop + 1);
}
/* DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
*
* Display information in the status line area.
*/
STATIC VOID
DoStatusInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
{
/* What mode of operation is the status area in? */
switch(Mode)
{
/* Compressed mode. */
case MODE_SCREEN_COMPRESSED:
{
struct RastPort *RPort = Object;
STATIC BYTE Offsets[8] =
{
0,
-1, /* Not supported */
26,
11,
40,
53,
61,
72
};
STATIC UBYTE Strings[8][20];
UBYTE LineBuffer[90];
LONG i,j,k,Width;
strcpy(Strings[Type],String);
strcpy(LineBuffer," · · · · · · ");
for(i = 0 ; i < 8 ; i++)
{
if(Offsets[i] >= 0)
{
j = strlen(Strings[i]);
for(k = 0 ; k < j ; k++)
LineBuffer[Offsets[i] + k] = Strings[i][k];
}
}
Width = TextLength(RPort,LineBuffer,80);
if((StatusLineWidth && StatusLineWidth != Width) || NeedFullRefresh)
{
LONG OldPen = ReadAPen(RPort);
SetAPen(RPort,Pens[TEXTPEN]);
FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
SetAPen(RPort,OldPen);
StatusLineWidth = Width;
NeedFullRefresh = FALSE;
}
PlaceText(RPort,StatusDisplayLeft + (StatusDisplayWidth - Width) / 2,StatusDisplayTop,LineBuffer,80);
}
break;
/* Normal mode. */
case MODE_SCREEN_NORMAL:
{
STATIC UBYTE Codes[8][2] =
{
STATUSBOX_STATUS_FONT, 0,
STATUSBOX_STATUS_FONT, 1,
STATUSBOX_PROTOCOL_TERMINAL, 0,
STATUSBOX_PROTOCOL_TERMINAL, 1,
STATUSBOX_RATE_PARAMETERS, 0,
STATUSBOX_RATE_PARAMETERS, 1,
STATUSBOX_TIME_ONLINE, 0,
STATUSBOX_TIME_ONLINE, 1
};
struct ObjectCarrier *Carrier = (struct ObjectCarrier *)Object;
if(Carrier->RPort)
{
if(NeedFullRefresh && !Config->ScreenConfig->SplitStatus)
{
struct RastPort *RPort = Carrier->RPort;
LONG Left;
if((Left = StatusDisplayLeft + (StatusDisplayWidth - Carrier->FullWidth) / 2) < 0)
Left = 0;
Left += Carrier->FirstColumn - SZ_GetBoxInfo(Carrier->BoxList,BOX_LEFT);
SetAPen(RPort,Pens[BACKGROUNDPEN]);
FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
DrawSeparator(RPort);
SZ_SetBoxes(Carrier->BoxList,-1,StatusDisplayTop + 3);
SZ_MoveBoxes(Carrier->BoxList,Left,0);
SZ_DrawBoxes(RPort,Carrier->BoxList);
NeedFullRefresh = FALSE;
}
SZ_PrintLine(Carrier->RPort,Carrier->BoxArray[Codes[Type][0]],Codes[Type][1],String);
}
}
break;
}
}
/* DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String):
*
* Post an update message to the status display server.
*/
STATIC VOID
DoInfo(APTR Object,UBYTE Mode,UBYTE Type,STRPTR String)
{
struct UpdateMessage *Msg;
LONG Len = strlen(String) + 1;
/* Allocate enough space to hold both the string
* and the message.
*/
if(Msg = (struct UpdateMessage *)AllocVecPooled(sizeof(struct UpdateMessage) + Len,MEMF_ANY | MEMF_CLEAR))
{
/* Fill in the message head. */
Msg->Message.mn_Length = sizeof(struct UpdateMessage) + Len;
/* Set up the name pointer. */
Msg->Message.mn_Node.ln_Name = (STRPTR)(Msg + 1);
/* Copy the string. */
strcpy(Msg->Message.mn_Node.ln_Name,String);
/* Fill in the remaining data. */
Msg->Object = Object;
Msg->Mode = Mode;
Msg->Type = Type;
/* Post the message. */
PutMsg(StatusDisplayPort,(struct Message *)Msg);
}
}
/* UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...):
*
* Update the information displayed in the status
* area.
*/
STATIC VOID
UpdateInfo(APTR Object,UBYTE Mode,UBYTE Type,...)
{
if(Object)
{
UBYTE MiniBuffer[50];
STRPTR *String;
LONG *Numeral;
va_list VarArgs;
va_start(VarArgs,Type);
String = (STRPTR *)VarArgs;
Numeral = (LONG *)VarArgs;
switch(Type)
{
case INFO_STATUS:
LimitedStrcpy(sizeof(MiniBuffer),MiniBuffer,LocaleString(ConfigStatusIDs[Numeral[0]]));
LimitedStrcat(sizeof(MiniBuffer),MiniBuffer," ");
MiniBuffer[9] = 0;
break;
case INFO_BUFFER:
if(Mode == MODE_SCREEN_NORMAL)
DoInfo(Object,Mode,Type,ConfigBufferState[Numeral[0]]);
va_end(VarArgs);
return;
case INFO_UNITTIME:
LimitedSPrintf(sizeof(MiniBuffer) - 1,&MiniBuffer[1],"%2ld:%02ld",Numeral[0] / 60,Numeral[0] % 60);
if(Numeral[0] > 0)
MiniBuffer[0] = '-';
else
MiniBuffer[0] = ' ';
Type = INFO_ONLINETIME;
break;
case INFO_ONLINECOST:
CopyMem(String[0],MiniBuffer,8);
LimitedStrcat(sizeof(MiniBuffer),MiniBuffer," ");
MiniBuffer[8] = 0;
Type = INFO_ONLINETIME;
break;
case INFO_CURRENTTIME:
FormatTime(MiniBuffer,sizeof(MiniBuffer),Numeral[0],Numeral[1],Numeral[2]);
break;
case INFO_ONLINETIME:
LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%02ld:%02ld:%02ld",Numeral[0],Numeral[1],Numeral[2]);
break;
case INFO_BAUDRATE:
if(LocaleBase)
LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%lD ",Numeral[0]);
else
LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%ld ",Numeral[0]);
MiniBuffer[7] = 0;
break;
case INFO_PROTOCOL:
case INFO_EMULATION:
CopyMem(String[0],MiniBuffer,12);
LimitedStrcat(sizeof(MiniBuffer),MiniBuffer," ");
MiniBuffer[12] = 0;
break;
case INFO_PARAMETERS:
if(Mode == MODE_SCREEN_COMPRESSED)
{
STATIC UBYTE Parities[5] =
{
'N','E','O','M','S'
};
LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%ld-%lc-%ld",Numeral[0],Parities[Numeral[1]],Numeral[2]);
}
else
LimitedSPrintf(sizeof(MiniBuffer),MiniBuffer,"%ld-%s-%ld",Numeral[0],ConfigParity[Numeral[1]],Numeral[2]);
break;
}
DoInfo(Object,Mode,Type,MiniBuffer);
va_end(VarArgs);
}
}
/* VisualBeep():
*
* Handle the visual part of the display beep.
*/
STATIC BOOL
VisualBeep(ColourTable **OldPtr,ColourTable **NewPtr)
{
ColourTable *Old,*New;
Old = CreateColourTable(Window->WScreen->ViewPort.ColorMap->Count,NULL,NULL);
New = CreateColourTable(Window->WScreen->ViewPort.ColorMap->Count,NULL,NULL);
if(New && Old)
{
ULONG Red,Green,Blue;
LONG i;
GrabColours(&Window->WScreen->ViewPort,Old);
CopyColours(Old,New);
for(i = 0 ; i < Old->NumColours ; i++)
{
Red = (Old->Entry[i].Red >> 24) + 64;
Green = (Old->Entry[i].Green >> 24) + 64;
Blue = (Old->Entry[i].Blue >> 24) + 64;
if(Red > 255)
Red = 255;
if(Green > 255)
Green = 255;
if(Blue > 255)
Blue = 255;
New->Entry[i].Red = SPREAD(Red);
New->Entry[i].Green = SPREAD(Green);
New->Entry[i].Blue = SPREAD(Blue);
}
*OldPtr = Old;
*NewPtr = New;
return(TRUE);
}
DeleteColourTable(Old);
DeleteColourTable(New);
*OldPtr = *NewPtr = NULL;
return(FALSE);
}
/* StatusDisplayServer(VOID):
*
* Yet another asynchronous background task to display
* some information.
*/
STATIC VOID SAVE_DS
StatusDisplayServer(VOID)
{
/* Create the interface port. */
if(StatusDisplayPort = CreateMsgPort())
{
struct UpdateMessage *Msg;
ULONG Signals;
/* Ring back... */
Signal((struct Task *)StatusProcess,SIG_HANDSHAKE);
/* Wait for messages or termination signal. */
FOREVER
{
Signals = Wait(SIG_KILL | PORTMASK(StatusDisplayPort));
/* Termination? */
if(Signals & SIG_KILL)
break;
/* Message arrival? */
if(Signals & PORTMASK(StatusDisplayPort))
{
/* Process all pending messages. */
while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
{
DoStatusInfo(Msg->Object,Msg->Mode,Msg->Type,Msg->Message.mn_Node.ln_Name);
FreeVecPooled(Msg);
}
}
}
/* Remove all pending messages. */
while(Msg = (struct UpdateMessage *)GetMsg(StatusDisplayPort))
FreeVecPooled(Msg);
/* Remove the msgport. */
DeleteMsgPort(StatusDisplayPort);
}
/* Lock & quit... */
Forbid();
StatusDisplayTask = NULL;
Signal((struct Task *)StatusProcess,SIG_HANDSHAKE);
RemTask(NULL);
}
/* StatusServer():
*
* Asynchronous process to continuosly display the current
* terminal settings.
*/
VOID SAVE_DS
StatusServer()
{
STATIC struct timeval OnlineTime,
DeltaTime,
LastTime,
PeriodTime;
STATIC LONG BeepCount;
STATIC BOOL LocalWasOnline;
BOOL LocalIsOnline;
BOOL PeriodAction;
struct TextBox *BoxArray[4],
*BoxList = NULL,
*Box;
struct RastPort *RPort;
APTR SomeObject;
struct ObjectCarrier Carrier;
struct timerequest *StatusTimeRequest;
struct MsgPort *StatusTimePort;
struct timeval Now;
BOOL Background = FALSE,
FlashIt = FALSE,
SetColours = FALSE,
StandardColours = TRUE,
KeepGoing = TRUE,
Beeping = FALSE;
WORD StatusMode = Config->ScreenConfig->StatusLine;
WORD ShowCounter = 0;
UBYTE LastProtocol[MAX_FILENAME_LENGTH],
LastEmulationName[MAX_FILENAME_LENGTH];
LONG LastFrozen = -1,
LastEmulation = -1,
LastBitsPerChar = -1,
LastParity = -1,
LastStopBits = -1,
LastStatus = -1;
LONG LastBaud = -1;
LONG i,
ThisHour,
ThisMinute,
BoxCounter = 0,
FullWidth;
LONG ColumnLeft[4],
ColumnWidth[4],
Max,
Len;
ColourTable *Old = NULL,
*New = NULL;
BOOL AllFine = TRUE;
LONG Mode;
StatusLineWidth = 0;
LastProtocol[0] = 0;
LastEmulationName[0] = 0;
LocalizeString(ConfigBufferState,MSG_TERMSTATUSDISPLAY_FROZEN_TXT,MSG_TERMSTATUSDISPLAY_RECORDING_TXT);
LocalizeString(ConfigEmulation,MSG_TERMAUX_ANSI_VT102_TXT,MSG_TERMAUX_HEX_TXT);
LocalizeString(ConfigParity,MSG_TERMAUX_NONE_TXT,MSG_TERMAUX_SPACE_TXT);
if(StatusWindow)
RPort = StatusWindow->RPort;
else
RPort = StatusRPort;
if(RPort)
{
SetAPen(RPort,Pens[BACKGROUNDPEN]);
FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
/* Render the information. */
if(StatusWindow)
SZ_SizeSetup(StatusWindow->WScreen,(struct TextAttr *)&UserFont);
else
SZ_SizeSetup(Window->WScreen,(struct TextAttr *)&UserFont);
if(StatusMode == STATUSLINE_COMPRESSED)
{
StatusOffset = (StatusDisplayWidth - 80 * UserFontWidth) / 2;
SetAPen(RPort,Pens[TEXTPEN]);
FillBox(RPort,StatusDisplayLeft,StatusDisplayTop,StatusDisplayWidth,StatusDisplayHeight);
SetPens(RPort,Pens[BACKGROUNDPEN],Pens[TEXTPEN],JAM2);
SetFont(RPort,UserTextFont);
}
else
{
SetBPen(RPort,Pens[BACKGROUNDPEN]);
/* Draw a separating line. */
if(!Config->ScreenConfig->SplitStatus)
DrawSeparator(RPort);
SetAPen(RPort,Pens[TEXTPEN]);
ColumnLeft[0] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_STATUS_TXT,MSG_TERMSTATUSDISPLAY_FONT_TXT,-1);
ColumnLeft[1] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT,MSG_TERMSTATUSDISPLAY_TERMINAL_TXT,-1);
ColumnLeft[2] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT,MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT,-1);
ColumnLeft[3] = SZ_LeftOffsetN(MSG_TERMSTATUSDISPLAY_TIME_TXT,MSG_TERMSTATUSDISPLAY_ONLINE_TXT,-1);
Max = 0;
for(i = 0 ; i < NUM_ELEMENTS(ConfigStatusIDs) ; i++)
{
if((Len = SZ_BoxWidth(strlen(LocaleString(ConfigStatusIDs[i])))) > Max)
Max = Len;
}
for(i = 0 ; ConfigBufferState[i] ; i++)
{
if((Len = SZ_BoxWidth(strlen(ConfigBufferState[i]))) > Max)
Max = Len;
}
ColumnWidth[0] = Max;
Max = SZ_BoxWidth(12);
for(i = 0 ; ConfigEmulation[i] ; i++)
{
if((Len = SZ_BoxWidth(strlen(ConfigEmulation[i]))) > Max)
Max = Len;
}
ColumnWidth[1] = Max;
Max = SZ_BoxWidth(10);
for(i = 0 ; ConfigParity[i] ; i++)
{
if((Len = SZ_BoxWidth(4 + strlen(ConfigParity[i]))) > Max)
Max = Len;
}
ColumnWidth[2] = Max;
ColumnWidth[3] = SZ_BoxWidth(8);
FullWidth = 0;
for(i = 0 ; i < 4 ; i++)
FullWidth += ColumnWidth[i] + ColumnLeft[i];
FullWidth += 4 + 3 * InterWidth;
Carrier.FullWidth = FullWidth;
Carrier.FirstColumn = ColumnLeft[0] + 2;
if(!Config->ScreenConfig->SplitStatus)
{
if(FullWidth > StatusDisplayWidth)
SZ_SetLeftEdge(StatusDisplayLeft + ColumnLeft[0] + 2);
else
SZ_SetLeftEdge(StatusDisplayLeft + (StatusDisplayWidth - FullWidth) / 2 + ColumnLeft[0] + 2);
SZ_SetAbsoluteTop(StatusDisplayTop + 3);
SZ_SetTopEdge(StatusDisplayTop + 3);
}
else
{
SZ_SetLeftEdge(StatusDisplayLeft + ColumnLeft[0] + 2);
SZ_SetAbsoluteTop(StatusDisplayTop + 1);
SZ_SetTopEdge(StatusDisplayTop + 1);
}
SZ_SetWidth(ColumnWidth[0]);
BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_STATUS_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_FONT_TXT),NULL);
SZ_SetWidth(ColumnWidth[1]);
SZ_AddLeftOffset(ColumnLeft[1]);
BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
SZ_NewColumn, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_PROTOCOL_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_TERMINAL_TXT),NULL);
SZ_SetWidth(ColumnWidth[2]);
SZ_AddLeftOffset(ColumnLeft[2]);
BoxArray[BoxCounter++] = Box = SZ_CreateTextBox(&BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
SZ_NewColumn, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_BAUDRATE_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_PARAMETERS_TXT),NULL);
SZ_SetWidth(ColumnWidth[3]);
SZ_AddLeftOffset(ColumnLeft[3]);
BoxArray[BoxCounter] = Box = SZ_CreateTextBox(&BoxList,
SZ_Lines, 2,
SZ_AutoWidth, TRUE,
SZ_NewColumn, TRUE,
TAG_DONE);
SZ_SetBoxTitles(Box,LocaleString(MSG_TERMSTATUSDISPLAY_TIME_TXT),LocaleString(MSG_TERMSTATUSDISPLAY_ONLINE_TXT),NULL);
if(!Box)
AllFine = FALSE;
else
SZ_DrawBoxes(RPort,BoxList);
}
}
else
AllFine = TRUE;
if((UpdateSig = AllocSignal(-1)) == -1)
AllFine = FALSE;
else
UpdateMask = 1L << UpdateSig;
/* Everything fine so far? */
if(AllFine)
{
Forbid();
/* Create the display server task. */
if(StatusDisplayTask = LocalCreateTask("term Status Display Task",5,(TASKENTRY)StatusDisplayServer,4000,0))
WaitForHandshake();
Permit();
}
/* Is the display server task up and running? */
if(StatusDisplayTask)
{
/* Create a timer device request. */
if(StatusTimePort = (struct MsgPort *)CreateMsgPort())
{
if(StatusTimeRequest = (struct timerequest *)CreateIORequest(StatusTimePort,sizeof(struct timerequest)))
{
if(!OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)StatusTimeRequest,0))
{
/* Signal our father process
* that we're running.
*/
Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
if(RPort)
{
if(StatusMode == STATUSLINE_COMPRESSED)
{
Mode = MODE_SCREEN_COMPRESSED;
SomeObject = RPort;
}
else
{
Mode = MODE_SCREEN_NORMAL;
Carrier.RPort = RPort;
Carrier.BoxArray = BoxArray;
Carrier.BoxList = BoxList;
SomeObject = &Carrier;
}
UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,0,0,0);
}
memset(&DeltaTime,0,sizeof(DeltaTime));
GetSysTime(&PeriodTime);
/* Keep on displaying. */
while(KeepGoing)
{
/* Are we to quit? */
if(SetSignal(0,SIG_KILL) & SIG_KILL)
KeepGoing = FALSE;
/* Get the current time. */
GetSysTime(&Now);
SafeObtainSemaphoreShared(&OnlineSemaphore);
/* A connection has just
* been established.
*/
if(Online && !LocalWasOnline)
{
OnlineTime = Now;
LocalWasOnline = TRUE;
}
ReleaseSemaphore(&OnlineSemaphore);
/* Print the current time. */
ThisHour = (Now.tv_secs % (24 * 60 * 60)) / (60 * 60);
ThisMinute = (Now.tv_secs % (60 * 60)) / 60;
UpdateInfo(SomeObject,Mode,INFO_CURRENTTIME,ThisHour,ThisMinute,Now.tv_secs % 60);
/* Handle routine checkup actions. */
if(PeriodAction = (BOOL)(PeriodTime.tv_secs < Now.tv_secs && Now.tv_secs - PeriodTime.tv_secs >= ROUTINE_CHECK_INTERVAL))
{
PeriodTime = Now;
Signal((struct Task *)ThisProcess,SIG_CHECK);
}
SafeObtainSemaphoreShared(&OnlineSemaphore);
LocalIsOnline = Online;
ReleaseSemaphore(&OnlineSemaphore);
if(LocalIsOnline)
{
/* Show the time we have been online
* so far.
*/
DeltaTime = Now;
SubTime(&DeltaTime,&OnlineTime);
if(Now.tv_secs != LastTime.tv_secs)
{
UBYTE Sum[20];
WORD What;
LastTime = Now;
switch(Config->ScreenConfig->TimeMode)
{
case ONLINETIME_TIME:
What = SHOW_OnlineTime;
break;
case ONLINETIME_COST:
What = SHOW_Cost;
break;
case ONLINETIME_BOTH:
if(PeriodAction)
ShowCounter = (ShowCounter + 1) % 3;
switch(ShowCounter)
{
case 0:
What = SHOW_OnlineTime;
break;
case 1:
What = SHOW_Cost;
break;
case 2:
What = SHOW_UnitTime;
break;
}
break;
}
OnlineMinutes = DeltaTime.tv_secs / 60;
switch(What)
{
case SHOW_OnlineTime:
UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(DeltaTime.tv_secs % 86400) / 3600,(DeltaTime.tv_secs % 3600) / 60,DeltaTime.tv_secs % 60);
break;
case SHOW_Cost:
CreateSum((QueryAccountantCost() + 5000) / 10000,TRUE,Sum,sizeof(Sum));
UpdateInfo(SomeObject,Mode,INFO_ONLINECOST,Sum);
break;
case SHOW_UnitTime:
UpdateInfo(SomeObject,Mode,INFO_UNITTIME,QueryAccountantTime(NULL));
break;
}
}
}
else
{
if(LocalWasOnline)
{
LocalWasOnline = FALSE;
UpdateInfo(SomeObject,Mode,INFO_ONLINETIME,(DeltaTime.tv_secs % 86400) / 3600,(DeltaTime.tv_secs % 3600) / 60,DeltaTime.tv_secs % 60);
}
}
/* Take care of the visual beep
* if enabled.
*/
if(Beeping)
{
if(!(BeepCount--))
{
Beeping = FALSE;
LoadColourTable(VPort,Old,NULL,0);
DeleteColourTable(Old);
DeleteColourTable(New);
Old = New = NULL;
/* Clear the signal bit. */
ClrSignal(SIG_BELL);
}
}
/* Are we to show a visual beep? */
if(SetSignal(0,SIG_BELL) & SIG_BELL)
{
if(Config->TerminalConfig->BellMode == BELL_SYSTEM)
DisplayBeep(Window->WScreen);
else
{
if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping && (Config->TerminalConfig->BellMode == BELL_VISIBLE || Config->TerminalConfig->BellMode == BELL_BOTH))
{
if(VisualBeep(&Old,&New))
{
LoadColourTable(VPort,New,NULL,0);
Beeping = TRUE;
BeepCount = 1;
}
}
}
}
/* Display the current terminal
* status.
*/
if(LastStatus != GetStatus())
UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = GetStatus());
/* Show the current transfer
* protocol.
*/
if(strcmp(LastProtocol,TransferProtocolName))
{
STRPTR String;
strcpy(LastProtocol,TransferProtocolName);
if(LastProtocol[0])
String = LastProtocol;
else
String = "-";
UpdateInfo(SomeObject,Mode,INFO_PROTOCOL,String);
}
/* Show the current baud
* rate.
*/
if(LastBaud != Config->SerialConfig->BaudRate)
UpdateInfo(SomeObject,Mode,INFO_BAUDRATE,LastBaud = Config->SerialConfig->BaudRate);
/* Show the current
* terminal font.
*/
if(LastFrozen != BufferFrozen)
{
LastFrozen = BufferFrozen;
UpdateInfo(SomeObject,Mode,INFO_BUFFER,LastFrozen != TRUE);
}
/* Show the current terminal
* emulation.
*/
if(LastEmulation != Config->TerminalConfig->EmulationMode || (Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL && Stricmp(EmulationName,LastEmulationName)))
{
LastEmulation = Config->TerminalConfig->EmulationMode;
if(Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
{
UpdateInfo(SomeObject,Mode,INFO_EMULATION,EmulationName);
strcpy(LastEmulationName,EmulationName);
}
else
UpdateInfo(SomeObject,Mode,INFO_EMULATION,ConfigEmulation[LastEmulation]);
}
/* Show the current serial
* parameters (parity, etc).
*/
if(LastBitsPerChar != Config->SerialConfig->BitsPerChar || LastParity != Config->SerialConfig->Parity || LastStopBits != Config->SerialConfig->StopBits)
{
LastBitsPerChar = Config->SerialConfig->BitsPerChar;
LastParity = Config->SerialConfig->Parity;
LastStopBits = Config->SerialConfig->StopBits;
UpdateInfo(SomeObject,Mode,INFO_PARAMETERS,LastBitsPerChar,LastParity,LastStopBits);
}
/* Wait another half a second. */
if(KeepGoing)
{
ULONG Mask;
BOOL ResetTime = FALSE;
StatusTimeRequest->tr_node.io_Command = TR_ADDREQUEST;
StatusTimeRequest->tr_time.tv_secs = 0;
StatusTimeRequest->tr_time.tv_micro = MILLION / 2;
SetSignal(0,PORTMASK(StatusTimePort));
SendIO((struct IORequest *)StatusTimeRequest);
FOREVER
{
Mask = Wait(SIG_BELL | PORTMASK(StatusTimePort) | SIG_CLOSEWINDOW | SIG_RESETTIME | UpdateMask);
if(Mask & UpdateMask)
{
Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
Wait(UpdateMask);
NeedFullRefresh = TRUE;
UpdateInfo(SomeObject,Mode,INFO_STATUS,LastStatus = GetStatus());
}
/* Close the window and keep quiet? */
if(Mask & SIG_CLOSEWINDOW)
{
Forbid();
ShakeHands(StatusDisplayTask,SIG_KILL);
if(BoxList)
{
SZ_FreeBoxes(BoxList);
BoxList = NULL;
}
SomeObject = NULL;
Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
Config->ScreenConfig->StatusLine = STATUSLINE_DISABLED;
Permit();
}
if(Mask & SIG_BELL)
{
if(Config->TerminalConfig->BellMode == BELL_SYSTEM)
DisplayBeep(Window->WScreen);
else
{
if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping && (Config->TerminalConfig->BellMode == BELL_VISIBLE || Config->TerminalConfig->BellMode == BELL_BOTH))
{
if(VisualBeep(&Old,&New))
{
LoadColourTable(VPort,New,NULL,0);
Beeping = TRUE;
BeepCount = 1;
}
}
}
}
/* Reset the online time counter. */
if(Mask & SIG_RESETTIME)
ResetTime = TRUE;
if(Mask & PORTMASK(StatusTimePort))
{
WaitIO((struct IORequest *)StatusTimeRequest);
break;
}
}
/* Reset the online time. */
if(ResetTime)
GetSysTime(&OnlineTime);
}
/* Make the colours blink. */
if(Screen && !Config->ScreenConfig->UseWorkbench && !Beeping)
{
if(Screen == IntuitionBase->FirstScreen)
{
/* No main screen window active? */
if(StatusWindow)
{
if(!(Window->Flags & WFLG_WINDOWACTIVE) && !(StatusWindow->Flags & WFLG_WINDOWACTIVE))
StandardColours = TRUE;
}
else
{
if(!(Window->Flags & WFLG_WINDOWACTIVE))
StandardColours = TRUE;
}
/* Menu button pressed or window disabled? */
if(Window->Flags & (WFLG_MENUSTATE | WFLG_INREQUEST))
StandardColours = TRUE;
/* User is currently dragging the
* mouse in order to mark something
* on the screen?
*/
if(Marking)
StandardColours = TRUE;
Background = FALSE;
}
else
{
if(!Background)
StandardColours = TRUE;
Background = TRUE;
}
if(StandardColours)
{
if(!SetColours)
{
LoadColourTable(VPort,NormalColourTable,NormalColours,PaletteSize);
SetColours = TRUE;
}
StandardColours = FlashIt = FALSE;
}
else
{
/* Are we to flash the display? */
if(Config->ScreenConfig->Blinking)
{
if(Screen == IntuitionBase->FirstScreen)
{
if(FlashIt)
{
LoadColourTable(VPort,BlinkColourTable,BlinkColours,PaletteSize);
SetColours = FALSE;
}
else
{
LoadColourTable(VPort,NormalColourTable,NormalColours,PaletteSize);
SetColours = TRUE;
}
}
FlashIt ^= TRUE;
}
}
}
}
CloseDevice((struct IORequest *)StatusTimeRequest);
}
DeleteIORequest((struct IORequest *)StatusTimeRequest);
}
DeleteMsgPort(StatusTimePort);
}
if(Old)
LoadColourTable(VPort,Old,NULL,0);
DeleteColourTable(Old);
DeleteColourTable(New);
ShakeHands(StatusDisplayTask,SIG_KILL);
if(BoxList)
SZ_FreeBoxes(BoxList);
}
if(UpdateSig != -1)
FreeSignal(UpdateSig);
/* Signal the father process that we're done
* and quietly remove ourselves.
*/
Forbid();
Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
StatusProcess = NULL;
}
/* ForceStatusUpdate():
*
* Make sure that the status display gets updated
* as soon as possible.
*/
VOID
ForceStatusUpdate()
{
if(StatusProcess && Window)
{
ShakeHands((struct Task *)StatusProcess,UpdateMask);
/* Ok, the status process is waiting, now update the data */
if(Marking)
WindowMarkerStop();
UpdateTerminalLimits();
/* Clear the window */
SetAPen(Window->RPort,Pens[BACKGROUNDPEN]);
FillBox(Window->RPort,Window->BorderLeft,Window->BorderTop,Window->Width - (Window->BorderLeft + Window->BorderRight),Window->Height - (Window->BorderTop + Window->BorderBottom));
/* Restart the status process */
Signal((struct Task *)StatusProcess,UpdateMask);
/* Repaint the window border, in case it got trashed */
RefreshWindowFrame(Window);
}
}